from django.db import models
#import random

class Config(models.Model):
    max_skills = models.IntegerField(default=3)
    action_points_per_tick = models.IntegerField(default=10)
    seconds_per_tick = models.IntegerField(default=3600)

class Skill(models.Model):
    name = models.CharField(max_length=30)
    
    def __unicode__(self):
        return self.name

class SkillTest(models.Model):
    skill = models.ForeignKey(Skill)
    dc = models.IntegerField(default=8)
    complete = models.BooleanField(default=False)
    completer = models.ForeignKey('Character', null=True)
    challenge = models.ForeignKey('SkillChallenge', null=True)

    def __unicode__(self):
        status = 'incomplete'
        if (self.complete):
            status = 'complete'
        return str(self.skill) + ' : ' + str(self.dc) + ' : ' + status

    def test(self, character, random):
        bonus = character.skill_bonus(self.skill)
        check = random.randint(1,20) + bonus
        if check >= self.dc:
            self.complete = True
            self.completer = character            
        return self.complete 

class SkillChallenge(models.Model):
    name = models.CharField(max_length=30, null=True)
    keywords = models.TextField(null=True)
    success_need = models.IntegerField(default=4)
    failures_limit = models.IntegerField(default=2)
    success_scored = models.IntegerField(default=0)
    failures_scored = models.IntegerField(default=0)
       
    def __unicode__(self):
        return self.name + ' : ' + str(self.complexity)
    
    def __complexity__(self):
        return self.success_need/2 - 1
        
    complexity = property(__complexity__)
    
    def __complete__(self):
        return self.success_scored == self.success_need
        
    complete = property(__complete__)

    def __failed__(self):
        return self.failures_scored == self.failures_limit
        
    failed = property(__failed__)

    def test(self, skilltest, character):
        result = False
        if skilltest.test(character):
            self.success_scored += 1
            result = True
        else:
            self.failures_scored += 1
        return result

class QuestModel(models.Model):
    name = models.CharField(max_length=255, blank=True, default='')
    keywords = models.TextField(null=True)
    holder = models.ForeignKey('Character', null=True, default=None)
    engage_actions = models.CharField(max_length=255, blank=True, default='')
    success = models.BooleanField(default=False)
    failed = models.BooleanField(default=False)
    reward = models.IntegerField(default=0)
    
    def is_complete(self):
        return self.success or self.failed
    
    def __unicode__(self):
        return self.name
    
class Name(models.Model):
    text = models.CharField(max_length=255, blank=True, default='')
    
    def __unicode__(self):
        return self.text

class Character(models.Model):
    name = models.ForeignKey(Name)
    skill_features = models.ManyToManyField(Skill, through='SkillFeature')
    npc = models.BooleanField()
    score = models.IntegerField(default=0)
    action_points = models.IntegerField(default=0)
    
    def __unicode__(self):
        if self.npc:
            return self.name.text + " : NPC."
        return self.name.text
    
    def skill_bonus(self, skill):
        result = 0
        for feature in self.skillfeature_set.filter(skill = skill):
            result += feature.bonus
        return result
        
    def train(self, skill):
        SkillFeature.objects.create(character=self, skill=skill, bonus=5, feature='trainning')
        

class SkillFeature(models.Model):
    character = models.ForeignKey(Character)
    skill = models.ForeignKey(Skill)
    bonus = models.IntegerField(default=0)
    feature = models.CharField(max_length=30)
        
class Location(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True, default='')
    initial = models.BooleanField(default=False)
    
    def __unicode__(self):
        return self.name
       
class Code(models.Model):
    code = models.TextField()
    desc = models.CharField(max_length=255)
    tags = models.CharField(max_length=255, null=True, default=None)
    
    def __eq__(self, object):
        return self.code == object.code
    
    def __get_code_array__(self):
        return self.code.split(';')
    
    def __set_code_array__(self, array):
        self.code = ';'.join(array)
        
    def __unicode__(self):
        return self.code
    
    code_array = property( __get_code_array__, __set_code_array__)

class Tick(models.Model):
    datetime = models.DateTimeField(auto_now_add=True)
    tick = models.IntegerField()
    
    def __unicode__(self):
        return str(self.tick) + " " + str(self.datetime)
    
    def __eq__(self, object):
        if type(object) == type(self):
            return self.tick == object.tick
        else:
            return False
    
    class Meta:
        get_latest_by = 'datetime'
      
class Event(models.Model):
    preconditions = models.ManyToManyField(Code, related_name='precondition_set')
    scheduled = models.BooleanField(default=False)
    schedule_start = models.ForeignKey(Tick, null=True, default=None, related_name='start_set')
    schedule_end = models.ForeignKey(Tick, null=True, default=None, related_name='end_set')
    player_will = models.BooleanField(default=False)
    recurring = models.BooleanField(default=False)
    timestamp = models.ForeignKey(Tick, null=True, related_name='firedevents')
    actions = models.ManyToManyField(Code, related_name='action_set')
    info = models.CharField(max_length=255, blank=True, default='')
    failed = models.BooleanField(default=False)
    description = models.CharField(max_length=255, blank=True, default='')
    online = models.BooleanField(default = False)
    current_offline = models.BooleanField(default = False)
    chatting = models.BooleanField(default = False)
    cost = models.IntegerField(default = 0)
    
    def __unicode__(self):
        return 'id=' + str(self.id) + " info=" + self.info + " timestamp=" + str(self.timestamp)
    
    class Meta:
        get_latest_by = 'timestamp__datetime'
    
class Item(models.Model):
    name = models.CharField(max_length=255)
    
    def __unicode__(self):
        return self.name
    
class Message(models.Model):
    text = models.TextField()
    
    def __unicode__(self):
        return '"' + self.text + '"'
    
class Speech(models.Model):
    begin = models.BooleanField(default = False)
    end = models.BooleanField(default = False)
    speaker = models.ForeignKey(Character, related_name="utterings")
    listener = models.ForeignKey(Character, related_name="listerings")
    interrupt = models.BooleanField(default = False)
    text = models.CharField(max_length=255, blank=True, default='')
    reply = models.CharField(max_length=255, blank=True, default='')
    branches = models.ManyToManyField('self', symmetrical =False)
    info = models.CharField(max_length=255, blank=True, default='')
    
    def __unicode__(self):
        return "speech: " + self.text + "."
    
class Option(models.Model):
    event = models.ForeignKey(Event)
    tick = models.ForeignKey(Tick)
    
    def __unicode__(self):
        return str(self.event)